home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / CPP / MRCLEAN.ZIP / DIALOGS.CPP next >
Encoding:
C/C++ Source or Header  |  1995-11-17  |  10.9 KB  |  343 lines

  1. //----------------------------------------------------------------------------
  2. // Mr.Clean v. 1.00 - (C) Copyright 1995 by Kent Reisdorph
  3. //
  4. // Novemeber 11, 1995
  5. //
  6. // dialogs.cpp - Source for dialogs used in Mr.Clean, an application
  7. // that cleans misc files out of Borland C++ project directories
  8. //
  9. //----------------------------------------------------------------------------
  10. #include "mrcmain.h"
  11. #pragma hdrstop
  12.  
  13. /// code for ChooseDirDialog /////////////////////////////////////
  14.  
  15. // response table. We had to create our own OK button and use it
  16. // because the commmon dialog OK button validates the filename field
  17. // which in our case will always be empty.
  18. DEFINE_RESPONSE_TABLE1(ChooseDirDialog, TFileOpenDialog)
  19.     EV_COMMAND(IDC_OK, CmOkClicked),
  20. END_RESPONSE_TABLE;
  21.  
  22. ChooseDirDialog::ChooseDirDialog(TWindow*        parent,
  23.                                         TData&          data,
  24.                                         TResId          templateId,
  25.                                         const char far* title,
  26.                                         TModule*        module)
  27.     : TFileOpenDialog(parent, data, templateId, title, module)
  28. {
  29.     // create a pointer to the static control that the common dialog
  30.     // uses to report the directory. We are going to take the text from
  31.     // this control later.
  32.     dir = new TStatic(this, 1088);
  33. }
  34.  
  35. void
  36. ChooseDirDialog::SetupWindow()
  37. {
  38.     TFileOpenDialog::SetupWindow();
  39.     // Gotta do this to get KB handling in the listbox. Evidently
  40.     // the common dialogs use a default ID of 1 to achieve this effect.
  41.     // This id, of course, conflicts with the BWCC OK button. For some
  42.     // strange reason the dialog will not come up if you remove the
  43.     // BWCC OK button, so I had to disable and make it !visible but it
  44.     // still had to be on the dialog. Strange!
  45.  
  46.     // Addendum: I decided not to use a BWCC dialog box for the
  47.     // ChooseDirDialog - too many problems.
  48.     SetDefaultId(1);
  49. }
  50.  
  51. // CmOkClicked(). Handler for our OK button. Just gets the text from the
  52. // static control and copies it to TOpenSave::TData.FileName. We could
  53. // do this other ways, but copying the directory to FileName follows
  54. // the OWL common dialog conventions.
  55. void
  56. ChooseDirDialog::CmOkClicked()
  57. {
  58.     char str[256];
  59.     dir->GetText(str, sizeof(str));
  60.     strcpy(Data.FileName, str);
  61.     TDialog::CmOk();
  62. }
  63.  
  64. /// code for TCenteredDialog /////////////////////////////////////
  65.  
  66. // SetupWindow(). To determine the x position we get the width of the
  67. // screen, divide by 2 to find the center, and subtract half the width
  68. // of the dialog. Likewise for y pos. That's the whole class.
  69. void TCenteredDialog::SetupWindow()
  70. {
  71.     TDialog::SetupWindow();
  72.     TRect rect = GetWindowRect();
  73.     int x = (GetSystemMetrics(SM_CXSCREEN)/2) - (rect.Width()/2);
  74.     int y = (GetSystemMetrics(SM_CYSCREEN)/2) - (rect.Height()/2);
  75.     SetWindowPos(0, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
  76. }
  77.  
  78. /// code for TimedDialog /////////////////////////////////////
  79.  
  80. // This class just pops up a dialog for the number of seconds passed
  81. // in the constructor's timeout parameter. Using a timeout of 0 will
  82. // leave the dialog on the screen. Clicking the left mouse button
  83. // closes the dialog
  84. DEFINE_RESPONSE_TABLE1(TimedDlg, TDialog)
  85.     EV_WM_TIMER,
  86.     EV_WM_LBUTTONDOWN,
  87. END_RESPONSE_TABLE;
  88.  
  89. TimedDlg::TimedDlg(TWindow* parent, int resId, const char far* text,
  90.     int timeout, TModule* module)
  91.         : TCenteredDialog(parent, resId, module)
  92. {
  93.     timeOut = timeout * 1000;
  94.     (const char far*)dlgText = text;
  95.   textWin = new TStatic(this, IDC_TEXT);
  96. }
  97.  
  98. void
  99. TimedDlg::SetupWindow()
  100. {
  101.     TCenteredDialog::SetupWindow();
  102.     textWin->SetText(dlgText);
  103.     if (timeOut) {
  104.         SetTimer(1, timeOut);
  105.     }
  106. }
  107.  
  108. void
  109. TimedDlg::EvTimer(UINT)
  110. {
  111.     KillTimer(1);
  112.     CloseWindow();
  113. }
  114.  
  115. void
  116. TimedDlg::EvLButtonDown(uint, TPoint&)
  117. {
  118.     CloseWindow();
  119. }
  120.  
  121. /// code for ConfigDialog /////////////////////////////////////
  122. DEFINE_RESPONSE_TABLE1(ConfigDlg, TDialog)
  123.     EV_BN_CLICKED(IDC_ADD, AddItem),
  124.     EV_BN_CLICKED(IDC_REMOVE, RemoveItem),
  125.     EV_BN_CLICKED(IDOK, CmOk),
  126.     EV_EN_CHANGE(IDC_EDIT, EditChanged),
  127.     EV_BN_CLICKED(IDC_DUMMY, DummyClicked),
  128.     EV_LBN_SELCHANGE(IDC_LISTBOX, SelChanged),
  129. END_RESPONSE_TABLE;
  130.  
  131. ConfigDlg::ConfigDlg(TWindow* parent)
  132.     : TCenteredDialog(parent, IDD_CONFIG),
  133.     fData(OFN_PATHMUSTEXIST, "", 0, "", "*")
  134. {
  135.     // set up the controls
  136.     listbox = new TListBox(this, IDC_LISTBOX);
  137.     edit = new TEdit(this, IDC_EDIT, 80);
  138.     dir = new TStatic(this, IDC_PATH);
  139.     addBtn = new TButton(this, IDC_ADD);
  140.     removeBtn = new TButton(this, IDC_REMOVE);
  141.     globalBtn = new TRadioButton(this, IDC_GLOBAL);
  142.     projectBtn = new TRadioButton(this, IDC_PROJECT);
  143. }
  144.  
  145. void
  146. ConfigDlg::SetupWindow()
  147. {
  148.     TCenteredDialog::SetupWindow();
  149.     // initially disable the add and remove buttons. We will enable
  150.     // them as conditions dictate
  151.     addBtn->EnableWindow(false);
  152.     removeBtn->EnableWindow(false);
  153.     // set the default for global configuration, not project specific
  154.     globalBtn->SetCheck(true);
  155.     projectBtn->SetCheck(false);
  156.     // set the default ID to a non-existant button. The response table
  157.     // sends the button press for the non-button to the DummyClicked
  158.     // function. This prevents the dialog from closing when the enter
  159.     // key is pressed.
  160.     SetDefaultId(IDC_DUMMY);
  161.     // read the mrclean.cfg file
  162.     ReadFile();
  163.     MrCleanWindow* w = dynamic_cast<MrCleanWindow*>(Parent);
  164.     dir->SetText(w->path);
  165. }
  166.  
  167. // AddItem() function. Takes the text from the edit control and adds
  168. // it to the listbox after doing some simple validation.
  169. void
  170. ConfigDlg::AddItem()
  171. {
  172.     char str[80];
  173.     // get the text from the edit control
  174.     edit->GetText(str, sizeof(str));
  175.     // if there is no text then return
  176.     if (strlen(str) == 0) return;
  177.     // if the user entered *.* then warn them
  178.     if (!strcmp(str, "*.*"))
  179.         if (MessageBox("WARNING!! This filespec will delete all files "
  180.             "in your project directory!", "Mr.Clean Warning",
  181.             MB_OKCANCEL | MB_ICONEXCLAMATION ) == IDCANCEL) { edit->Clear(); return; }
  182.     // I like the string class for manipulating strings
  183.     string s(str);
  184.     // if the more than 3 characters follow the '.' then the filespec
  185.     // is invalid. Beep and return (don't add the string to the listbox).
  186.     if (s.find_first_of(".") < s.length()- 4) { MessageBeep(-1); return; }
  187.     // convert the string to upper case - no reason, really
  188.     strupr(str);
  189.     // add the string to the listbox
  190.     listbox->AddString(str);
  191.     // now that we have strings in the listbox we can enable the "Remove" button.
  192.     removeBtn->EnableWindow(true);
  193.     // clear the edit control
  194.     edit->Clear();
  195.     // set focus back to the edit control
  196.     edit->SetFocus();
  197. }
  198.  
  199. // RemoveItem(). Message handler function for the "Remove" button.
  200. // removes an entry from the listbox
  201. void
  202. ConfigDlg::RemoveItem()
  203. {
  204.     // remove the string at the currently selected location
  205.     listbox->DeleteString(listbox->GetSelIndex());
  206.     // if no more entries remain in the list box then disable the
  207.     // "Remove" button.
  208.     if (listbox->GetCount() == 0) removeBtn->EnableWindow(false);
  209. }
  210.  
  211. // CmOk(). Called when the user clicks OK. We need to write the
  212. // config file if OK was clicked.
  213. void
  214. ConfigDlg::CmOk()
  215. {
  216.     char temp[256];
  217.     // get a pointer to the parent window
  218.     MrCleanWindow* w = dynamic_cast<MrCleanWindow*>(Parent);
  219.     // if the global button was not checked then the Project Specific
  220.     // button was checked.
  221.     if (!globalBtn->GetCheck()) {
  222.         // if a path was not passed in the command line then we need to
  223.         // pop up the FileSave common dialog so the user can select the
  224.         // project directory for the config file.
  225.         if (!strcmp(w->path, "")) {
  226.             //strcpy(fData.FileName, "mrclean.cfg");
  227.             if ((new ChooseDirDialog(
  228.                 this, fData, IDD_CHOOSEDIR)->Execute()) == IDCANCEL) return;
  229.             wsprintf(temp, "%s\\", fData.FileName);
  230.             // change the path member of MrCleanWindow to reflect the new path
  231.             strcpy(w->path, temp);
  232.             dir->SetText(temp);
  233.             strcat(temp, "mrclean.cfg");
  234.             return;
  235.         }
  236.         // if a path was passed in the command line then use it
  237.         else wsprintf(temp, "%smrclean.cfg", w->path);
  238.     }
  239.     // if the Global button is checked then use the Mr.Clean directory
  240.     // The parent's cfgFile member contains the path and filename
  241.     else strcpy(temp, w->cfgFile);
  242.     // open a file for output
  243.     ofstream outfile(temp);
  244.     // something went wrong
  245.     if (!outfile) {
  246.         MessageBox("Error Opening Config File", "Mr. Clean Error",
  247.             MB_OK | MB_ICONEXCLAMATION);
  248.         Destroy();
  249.     }
  250.     // write the check states of the 20 buttons. The control IDs
  251.     // are sequential to make this easy.
  252.     for (int i=101;i<124;i++) {
  253.         int check = (int)SendDlgItemMsg(i, BM_GETCHECK, 0, 0);
  254.         outfile << check << endl;
  255.     }
  256.     char str[80];
  257.     // any items in the list box?
  258.     int count = listbox->GetCount();
  259.     // write the number of items to the file
  260.     outfile << count << endl;
  261.     // get each string out of the listbox and write it to the file
  262.     for (i=0;i<count;i++) {
  263.         listbox->GetString(str, i);
  264.         outfile << str << endl;
  265.     }
  266.     // close the file
  267.     outfile.close();
  268.     // all done - close the dialog
  269.     TDialog::CmOk();
  270. }
  271.  
  272. // ReadFile()
  273. void
  274. ConfigDlg::ReadFile()
  275. {
  276.     // get a pointer to the parent window
  277.     MrCleanWindow* w = dynamic_cast<MrCleanWindow*>(Parent);
  278.     char temp[256];
  279.     // need this for the OpenFile function
  280.     OFSTRUCT ofStruct;
  281.     // first check to see if a mrclean.cfg file exists in the path
  282.     // passed in the command line
  283.     wsprintf(temp, "%smrclean.cfg", w->path);
  284.     // use OpenFile with the OF_EXIST flag. This opens the file and then
  285.     // closes it again. If the file does not exist then -1 is returned.
  286.     if (OpenFile(temp, &ofStruct, OF_EXIST) == -1) {
  287.         // no file? Ok, then use the default mrclean.cfg and set the
  288.         // radio buttons to Global
  289.         strcpy(temp, w->cfgFile);
  290.         globalBtn->SetCheck(true);
  291.         projectBtn->SetCheck(false);
  292.     }
  293.     // file does exist in the path provided? Use it and set the radio
  294.     // buttons to Project Specific
  295.     else
  296.         if (strcmp(w->path, "")) {
  297.             projectBtn->SetCheck(true);
  298.             globalBtn->SetCheck(false);
  299.         }
  300.     // open a file for output
  301.     ifstream infile(temp);
  302.     // we don't really need a config file so if it doesn't
  303.     // exist we will just create a new one.
  304.     if (!infile) return;
  305.     // read the values for each checkbox control and set the check state
  306.     // of the button with that value.
  307.     for (int i=101;i<124;i++) {
  308.         int val;
  309.         infile >> val;
  310.         SendDlgItemMsg(i, BM_SETCHECK, val, 0);
  311.     }
  312.     int count;
  313.     char str[80];
  314.     // get the number of strings to put into the listbox
  315.     infile >> count;
  316.     // if count is non-zero read that many string and stick them
  317.     // into the listbox.
  318.     if (count) {
  319.         for(i=0;i<count;i++) {
  320.             infile >> str;
  321.             listbox->AddString(str);
  322.         }
  323.     }
  324.     // all done - close the file
  325.     infile.close();
  326. }
  327.  
  328. // EditChanged() Called in response to a EN_CHANGE message. Used
  329. // to enable or disable the Add button.
  330. void
  331. ConfigDlg::EditChanged()
  332. {
  333.     char str[80];
  334.     // get the text from the edit control
  335.     edit->GetText(str, sizeof(str));
  336.     // if there is text then enable the Add button
  337.     if (strlen(str) > 0) addBtn->EnableWindow(true);
  338.     // if there is no text then disable the Add button. The user could
  339.     // enter text and then backspace until no text remains.
  340.     else addBtn->EnableWindow(false);
  341. }
  342.  
  343.